// 队列 Queue
// 1.队列是一个有序列表，可以用数组或是链表来实现
// 2.遵循 先进先出 的原则

// 数组实现
class CircleArrayQueue {
    constructor (arrMaxSize) {
        this.maxSize = arrMaxSize       // 数组的最大容量
        this.arr = Array(arrMaxSize)    // 模拟队列
        this.front = 0                 // 指向第一个元素
        this.rear = 0                  // 指向最后一个元素的的后一个位置 空一个位置 实际有效位置为arrMaxSize - 1
    }

    // 判断队列是否已满
    isFull () {
        return (this.rear + 1) % this.maxSize === this.front
    }

    // 判断队列是否为空
    isEmpty () {
        return this.front === this.rear
    }

    // 添加数据到队列
    add (n) {
        if (this.isFull()) {
            console.log('队列满，不能继续添加')
            return
        }

        this.arr[this.rear] = n
        this.rear = (this.rear + 1) % this.maxSize
        console.log('添加:', n)
        console.log('arr:', this.arr, 'front:', this.front, 'rear:', this.rear)
    }

    // 取数据
    get () {
        if (this.isEmpty()) {
            console.log('队列空，不能取数据')
            return
        }
        let res = this.arr[this.front]
        this.front = (this.front + 1) % this.maxSize
        console.log('取出:', res)
        return res
    }

    // 有效数据个数
    size () {
        return (this.rear + this.maxSize - this.front) % this.maxSize
    }

    show () {
        if (this.isEmpty()) {
            console.log('队列空')
            return
        }
        let res = []
        let sum = this.size()
        for (let i = this.front; i < sum + this.front; i++) {
            res.push(this.arr[i % this.maxSize])
        }
        console.log('队列:', res)
        return res
    }

    // 显示头数据
    showFront () {
        if (this.isEmpty()) {
            console.log('队列空，没有数据')
            return
        }
        return this.arr[this.front]
    }
}

function main () {
    let arrQueue = new CircleArrayQueue(3)
    arrQueue.add(1)
    arrQueue.add(2)
    arrQueue.add(3)
    arrQueue.show()
    arrQueue.get()
    arrQueue.show()
    arrQueue.add(4)
    arrQueue.show()
    arrQueue.add(5)
}

main()
